package com.clgk.wechatmall.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;

public class GeocoderUtils {
//    private static String AK = "AEb0131a50350625a882ec3a84f64940";
    
    private static List<String> keylist=new ArrayList<String>(); 
    static{
    	keylist.add("1lK0D9zkEzQuDnSIoZgLQYE5");//企业级账号
//    	keylist.add("hmKWGan45GdKl76hGyawKrLk");
//    	keylist.add("UWtNoSjGImHKChgGZwBOnC9h");
//    	keylist.add("TiONZhevfaoxeoAWFuoZY0eZ");
//    	keylist.add("S3mvd1evnPnu0VEzzKrOKoWt");
//    	keylist.add("A86ab64d954669382be5f3e1f30f3bf1");
    }
    
    private static Map<PoiType, CoordConvertType> map = new HashMap<PoiType, CoordConvertType>();

    private static Map<PoiType, CoordConvertType> poiTypeMapping = new HashMap<PoiType, CoordConvertType>();

    static {
        map.put(PoiType.GPS, CoordConvertType.GPS_TO_BAIDU);
        map.put(PoiType.GOOGLE, CoordConvertType.GOOGLE_TO_BAIDU);

        poiTypeMapping.put(PoiType.GPS, CoordConvertType.BAIDU_TO_GPS);
        poiTypeMapping.put(PoiType.GOOGLE, CoordConvertType.BAIDU_TO_GOOGLE);
    }
    
    
    /**
     * 取得随机的百度访问密钥(ak)
     * @return
     */
	public static String getRandomBaiDuKey()
    {
		int n=Integer.parseInt(getRandomCode(1));
	    return keylist.get(n);
    }
	
	/**
     * 取得指定长度的随机数字
     * @param length
     * @return
     */
	public static String getRandomCode(int length)
    {
        char[] codeList= {'0'};
//        char[] codeList= {'0','1', '2', '3', '4', '5'};
    	StringBuilder sb = new StringBuilder();
        Random random = new Random();
        int len=codeList.length;
        for (int i = 0; i < length; i++)
        {
            sb.append(codeList[random.nextInt(len)]);
        }
        
        return sb.toString();
    }

    /**
     * 获取经纬度（百度）对应的地址
     *
     * @param lng
     * @param lat
     * @return
     */
    public String getAddr(double lng, double lat) {
        return this.getAddr(lng, lat, PoiType.BAIDU);
    }

    /**
     * 获取经纬度对应的地址
     *
     * @param lng
     * @param lat
     * @param poiType 坐标的类型
     * @return
     */
    public String getAddr(double lng, double lat, PoiType poiType) {
        return this.getAddressComponent(lng, lat, poiType).getAddr();
    }

    /**
     * 获取经纬度所对应城市
     *
     * @param lng
     * @param lat
     * @param poiType 坐标的类型
     * @return
     */
    public String getCity(double lng, double lat, PoiType poiType) {
        return this.getAddressComponent(lng, lat, poiType).getCity();
    }

    /**
     * 获取经纬度对应的地址明细（省市区、街道等）
     * @param lng
     * @param lat
     * @param poiType
     * @return
     */
    public AddressComponent getAddressComponent(double lng, double lat, PoiType poiType) {
        String url = "http://api.map.baidu.com/geocoder/v2/";
        Map<String, String> params = new HashMap<String, String>();
        String coordtype = "bd09ll";
        if (poiType == PoiType.BAIDU) {
            coordtype = "bd09ll";
        } else if (poiType == PoiType.GPS) {
            coordtype = "wgs84ll";
        } else if (poiType == PoiType.GOOGLE) {
            double[] point = CoordConvertorUtils.convert(lng, lat, CoordConvertType.GOOGLE_TO_GPS);
            lng = point[0];
            lat = point[1];
            coordtype = "wgs84ll";
        }
        params.put("coordtype", coordtype);//坐标的类型，目前支持的坐标类型包括：bd09ll（百度经纬度坐标）、gcj02ll（国测局经纬度坐标）、wgs84ll（ GPS经纬度）
        params.put("location", lat + "," + lng);
        params.put("output", "json");
        params.put("pois", "0");
        params.put("ak", getRandomBaiDuKey());

        HttpUtils httpUtils = new HttpUtils();
        String response = null;
        AddressComponent address = new AddressComponent();
        try {
            response = httpUtils.post(url, params);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode JsonNode = objectMapper.readTree(response);
            JsonNode statusNode = JsonNode.get("status");

            int status = -1;
            if (statusNode != null) {
                status = statusNode.getIntValue();
            }
            if (status == 0) {
                JsonNode resultNode = JsonNode.get("result");
                JsonNode addressNode = resultNode.get(
                        "formatted_address");
                if (addressNode != null) {
                    address.setAddr(addressNode.getTextValue());
                }
                JsonNode addressComponentNode = resultNode.get("addressComponent");
                if (addressComponentNode != null) {
                    address.setCity(addressComponentNode.get("city").getTextValue());
                    address.setCountry(addressComponentNode.get("country").getTextValue());
                    address.setCountrycode(addressComponentNode.get("country").getTextValue());
                    address.setDirection(addressComponentNode.get("direction").getTextValue());
                    address.setDistance(addressComponentNode.get("distance").getTextValue());
                    address.setDistrict(addressComponentNode.get("district").getTextValue());
                    address.setProvince(addressComponentNode.get("province").getTextValue());
                    address.setStreet(addressComponentNode.get("street").getTextValue());
                    address.setStreetnumber(addressComponentNode.get("street_number").getTextValue());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return address;
    }

    /**
     * 获取地址对应的经纬度
     * @param address
     * @param poiType
     * @return
     */
    public double[] getPoint(String address, PoiType poiType) {
        double[] point = this.getPoint(address);
        CoordConvertType poiConvertType = poiTypeMapping.get(poiType);
        if (poiConvertType != null) {
            double[] newPoint = CoordConvertorUtils.convert(point[0], point[1],
                    poiConvertType);
            return newPoint;
        }
        return point;
    }

    public double[] getPoint(String address) {
        String url = "http://api.map.baidu.com/geocoder/v2/";
        Map<String, String> params = new HashMap<String, String>();
        params.put("address", address);
        params.put("output", "json");
        params.put("ak", getRandomBaiDuKey());

        HttpUtils httpUtils = new HttpUtils();
        String response;
        double[] point = new double[2];
        try {
            response = httpUtils.post(url, params);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode JsonNode = objectMapper.readTree(response);
            JsonNode statusNode = JsonNode.get("status");
            int status = -1;
            if (statusNode != null) {
                status = statusNode.getIntValue();
            }
            if (status == 0) {
                JsonNode locationNode = JsonNode.get("result").get("location");
                if (locationNode != null) {
                    point[0] = locationNode.get("lng").getDoubleValue();
                    point[1] = locationNode.get("lat").getDoubleValue();
                }
            } else {
                point = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return point;
    }

    /**
     * 经纬度解析地址
     *
     * @param lng BAIDU经度
     * @param lat BAIDU纬度
     * @return
     */
    public String reverseGeocoding(double lng, double lat, CoordType coordType) {
        String url = "http://api.map.baidu.com/telematics/v3/reverseGeocoding";
        Map<String, String> params = new HashMap<String, String>();
        params.put("location", lng + "," + lat);
        params.put("output", "json");
        params.put("coord_type", coordType.getValue());// 请求参数坐标类型，默认为gcj02经纬度坐标。允许的值为bd09ll、bd09mc、gcj02、wgs84。bd09ll表示百度经纬度坐标，bd09mc表示百度墨卡托坐标，gcj02表示经过国测局加密的坐标，wgs84表示gps获取的坐标。
        params.put("ak", getRandomBaiDuKey());

        HttpUtils httpUtils = new HttpUtils();
        String response = null;
        String addr = null;
        try {
            response = httpUtils.get(url, params);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(response);
            JsonNode statusNode = jsonNode.get("status");

            String status = "";
            if (statusNode != null) {
                status = statusNode.getTextValue();
            }
            if ("Success".equals(status)) {
                JsonNode addressNode = jsonNode.get("description");
                if (addressNode != null) {
                    addr = addressNode.getTextValue();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return addr;
    }

    public double[] geocoding(String address, CoordType outCoordType,
                              String cityName) {
        String url = "http://api.map.baidu.com/telematics/v3/geocoding";
        Map<String, String> params = new HashMap<String, String>();
        params.put("keyWord", address);
        params.put("output", "json");
        params.put("cityName", cityName);
        params.put("out_coord_type", "gcj02");
        params.put("ak", getRandomBaiDuKey());

        HttpUtils httpUtils = new HttpUtils();
        String response;
        double[] point = new double[2];
        try {
            response = httpUtils.get(url, params);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode JsonNode = objectMapper.readTree(response);
            JsonNode statusNode = JsonNode.get("status");
            String status = "";
            if (statusNode != null) {
                status = statusNode.getTextValue();
            }
            if ("Success".equals(status)) {
                JsonNode locationNode = JsonNode.get("results").get("location");
                if (locationNode != null) {
                    point[0] = locationNode.get("lng").getDoubleValue();
                    point[1] = locationNode.get("lat").getDoubleValue();
                }
            } else {
                point = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return point;
    }

    public static void main(String[] args) {
        // try {
        // String res = new HttpUtils()
        // .post("http://api.map.baidu.com/geocoder/v2/?address=%E6%97%A0%E9%94%A1%E5%A4%AA%E6%B9%96%E5%AD%A6%E9%99%A2&output=json&ak=AEb0131a50350625a882ec3a84f64940",
        // null);
        // System.out.println(res);
        // } catch (Exception e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }

        try {
            // double[] point = new GeocoderUtils().getPoint("北京工业大学");
            // System.out.println(point[0]);
            // System.out.println(point[1]);
            //

//            System.out.println(ArrayUtils.toString(new GeocoderUtils()
//                    .getPoint("广东省深圳市宝安区宝民二路111号")));
//            System.out.println(new GeocoderUtils().getAddr(113.88101549613705,
//                    22.5822571919519, PoiType.GPS));
//
//            System.out.println(ArrayUtils.toString(new GeocoderUtils()
//                    .geocoding("广东省深圳市宝安区宝民二路111号", CoordType.WGS84, "深圳")));
//            System.out.println(new GeocoderUtils().reverseGeocoding(
//                    113.88101549613705, 22.5822571919519, CoordType.WGS84));


            System.out.println(new GeocoderUtils().getAddressComponent(113.88101549613705,
                    22.5822571919519, PoiType.BAIDU).getCountry());
            System.out.println(new GeocoderUtils().getCity(113.88101549613705,
                    22.5822571919519, PoiType.BAIDU));

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
